//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
/*++
"This software program is available to you under a choice of one of two 
licenses.  You may choose to be licensed under either the GNU General Public 
License (GPL) Version 2, June 1991, available at 
http://www.fsf.org/copyleft/gpl.html, or the BSD License, the text of
which follows:

Copyright (c) 1996-2005, Intel Corporation. All rights reserved.

Redistribution and use in source and binary forms, with or without 
modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this 
list of conditions and the following disclaimer. 

Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or 
other materials provided with the distribution. 

Neither the name of the Intel Corporation ("Intel") nor the names of its 
contributors may be used to endorse or promote products derived from this
software without specific prior written permission. 

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
--*/

#ifndef __XLLP_DFC_H
#define __XLLP_DFC_H

#include "xllp_defs.h"
#include "xllp_mfp.h"
#include "xllp_ost.h"
//#include "xllp_clkmgr.h"

// The Data Flash Controller Registers structure
typedef struct {
	XLLP_VUINT32_T		ndcr; 	      // Data Flash Control Register
	XLLP_VUINT32_T		ndtr0cs0; 	  // Timing Parameter 0 Register
	XLLP_VUINT32_T  	resrved0; 	  // Reserved 0x43100008
	XLLP_VUINT32_T		ndtr1cs0; 	  // Timing Parameter 1 Register
	XLLP_VUINT32_T  	resrved1; 	  // Reserved 0x43100010
	XLLP_VUINT32_T		ndsr;	  		  // Data Controller Status	Register
	XLLP_VUINT32_T		ndpcr;			  // Data Controller Page Count Register
	XLLP_VUINT32_T		ndbdr0;			  // Data Controller Bad Block Register 0
	XLLP_VUINT32_T		ndbdr1;			  // Data Controller Bad Block Register 1
	XLLP_VUINT32_T  	resrved2[7];  // Reserved 0x43100024 - 0x4310003C
	XLLP_VUINT32_T		nddb;	  		  // Data Controller Data Register
	XLLP_VUINT32_T  	resrved3; 	  // Reserved 0x43100044
	XLLP_VUINT32_T		ndcb0;			  // Data Controller Command Buffer 0
	XLLP_VUINT32_T		ndcb1;			  // Data Controller Command Buffer 1
	XLLP_VUINT32_T		ndcb2;			  // Data Controller Command Buffer 2
} XLLP_DFC_REG_T, *P_XLLP_DFC_REG_T;


// The Data Flash Controller Flash timing structure
// For NAND flash used on Zylonite board(Samsung K9K1216Q0C),
// user should use value at end of each row of following member
// ,bracketed.
typedef struct {
	XLLP_UINT32_T   tCH;  		// Enable signal hold time. [10]
	XLLP_UINT32_T   tCS;  		// Enable signal setup time.[0]
	XLLP_UINT32_T   tWH;  		// ND_nWE high duration.[20]
	XLLP_UINT32_T   tWP;  		// ND_nWE pulse time.[40]
	XLLP_UINT32_T   tRH;  		// ND_nRE high duration.[20]
	XLLP_UINT32_T   tRP;  		// ND_nRE pulse width.[40]
	XLLP_UINT32_T   tR;   		// ND_nWE high to ND_nRE low for read.[11123]
	XLLP_UINT32_T   tWHR; 		// ND_nWE high to ND_nRE low delay for status read.[110]
	XLLP_UINT32_T   tAR;  		// ND_ALE low to ND_nRE low delay.[10]
} XLLP_DFC_FLASH_TIMING_T;


// The Data Flash Controller Flash specification structure
// For NAND flash used on Zylonite board(Samsung K9K1216Q0C),
// user should use value at end of each row of following member
// ,bracketed.
typedef struct {
  XLLP_DFC_FLASH_TIMING_T	timing;		// NAND Flash timing
	XLLP_UINT32_T   enableBusArbiter; // Data flash bus arbiter enable (ND_ARB_EN).[1]
  XLLP_UINT32_T   pagePerBlock;  		// Pages per block (PG_PER_BLK). [32]
  XLLP_UINT32_T   rowAddrStart;  		//  Row address start position (RA_START).[0]
  XLLP_UINT32_T   byteCntReadID; 		// returned ID bytes(RD_ID_CNT).[4]
  XLLP_UINT32_T   dfcMode;   				// NAND, CARBONDALE, PIXLEY... (ND_MODE)[0]
  XLLP_UINT32_T   ncsx; 						// Chip select don't care bit (NCSX).[0]
  XLLP_UINT32_T   pageSize;  	   		// Page size in bytes (PAGE_SZ).[512]
  XLLP_UINT32_T   widthFlash; 			// Width of Flash memory (DWIDTH_M).[16]
  XLLP_UINT32_T   widthDFC; 	      // Width of flash controller(DWIDTH_C).[16]
  XLLP_UINT32_T   numBlocks;        // Number of physical blocks in Flash.[4096]
	
	// command codes
	XLLP_UINT32_T   read1;			// Read. [0x0000]
	XLLP_UINT32_T   read2;      // unused, DFC don't support yet.[0x0050]
	XLLP_UINT32_T   program;    // two cycle command;[0x1080]
	XLLP_UINT32_T   readStatus; // [0x0070]
	XLLP_UINT32_T   readID;			// [0x0090]
	XLLP_UINT32_T   erase;		  // two cycle command.[0xD060]
	XLLP_UINT32_T   reset;		  // [0x00FF]
	XLLP_UINT32_T   lock;				// lock whole flash.[0x002A]
	XLLP_UINT32_T   unlock;		  // two cycle command, supporting partial unlock.[0x2423]
	XLLP_UINT32_T   lockStatus;	// read block lock status.[0x007A]
} XLLP_DFC_FLASH_SPECS_T, *P_XLLP_DFC_FLASH_SPECS_T;

// The Data Flash Controller Mode structure
typedef struct {
	XLLP_UINT32_T   enableDMA;          // DMA, or nonDMA mode
	XLLP_UINT32_T   enableECC;          // ECC on/off 
	XLLP_UINT32_T   enableSpareArea; 	// Spare enable
	XLLP_UINT32_T   chipSelect;			// CS0 or CS1
} XLLP_DFC_MODE_T, *P_XLLP_DFC_MODE_T;

// The Data Flash Controller Context structure
typedef struct {
	P_XLLP_DFC_REG_T   					pDFCReg;    // DFC register base
	P_XLLP_DFC_FLASH_SPECS_T   	pFlashInfo;// Flash Spec. structure
	P_XLLP_DFC_MODE_T   				pDFCMode;	  // DFC mode of operation structure
	P_XLLP_VUINT32_T   					pMFPBase;   // MFPR base address
	P_XLLP_MFP_RM_DB_ID_T  			pMFPRmDb;  	// MFP Resource Manager database
	P_XLLP_OST_T       					pOSTReg;	  // OST reg base, for busy delay
	//P_XLLP_DFC_DMA_CONTEXT_T    pDma;		  // DMA context structure used by DFC
} XLLP_DFC_CONTEXT_T, *P_XLLP_DFC_CONTEXT_T;

// register masks

// DFC ndsr register for interrupt
#define XLLP_DFC_INT_WRCMDREQM      XLLP_BIT_0
#define XLLP_DFC_INT_RDDREQM		    XLLP_BIT_1
#define XLLP_DFC_INT_WRDREQM		    XLLP_BIT_2
#define XLLP_DFC_INT_SBERRM			    XLLP_BIT_3
#define XLLP_DFC_INT_DBERRM			    XLLP_BIT_4
#define XLLP_DFC_INT_CS1_BBDM		    XLLP_BIT_5
#define XLLP_DFC_INT_CS0_BBDM		    XLLP_BIT_6
#define XLLP_DFC_INT_CS1_CMDDM		  XLLP_BIT_7
#define XLLP_DFC_INT_CS0_CMDDM		  XLLP_BIT_8
#define XLLP_DFC_INT_CS1_PAGEDM		  XLLP_BIT_9
#define XLLP_DFC_INT_CS0_PAGEDM		  XLLP_BIT_10
#define XLLP_DFC_INT_RDYM			    	XLLP_BIT_11

// DFC ndsr register for status
#define XLLP_DFC_STATUS_WRCMDREQ		XLLP_BIT_0
#define XLLP_DFC_STATUS_RDDREQ			XLLP_BIT_1
#define XLLP_DFC_STATUS_WRDREQ			XLLP_BIT_2
#define XLLP_DFC_STATUS_SBERR			XLLP_BIT_3
#define XLLP_DFC_STATUS_DBERR			XLLP_BIT_4
#define XLLP_DFC_STATUS_CS1_BBD			XLLP_BIT_5
#define XLLP_DFC_STATUS_CS0_BBD			XLLP_BIT_6
#define XLLP_DFC_STATUS_CS1_CMDD		XLLP_BIT_7
#define XLLP_DFC_STATUS_CS0_CMDD		XLLP_BIT_8
#define XLLP_DFC_STATUS_CS1_PAGED		XLLP_BIT_9
#define XLLP_DFC_STATUS_CS0_PAGED		XLLP_BIT_10
#define XLLP_DFC_STATUS_RDY				XLLP_BIT_11


// DFC control register
#define XLLP_DFC_CTRL_ND_ARB_EN			XLLP_BIT_12
#define XLLP_DFC_CTRL_PG_PER_BLK		XLLP_BIT_14
#define XLLP_DFC_CTRL_RA_START			XLLP_BIT_15
#define XLLP_DFC_CTRL_RD_ID_CNT			XLLP_BIT_16
#define XLLP_DFC_CTRL_CLR_ECC				XLLP_BIT_19
#define XLLP_DFC_CTRL_CLR_PG_CNT		XLLP_BIT_20
#define XLLP_DFC_CTRL_ND_MODE				XLLP_BIT_21
#define XLLP_DFC_CTRL_NCSX					XLLP_BIT_23
#define XLLP_DFC_CTRL_PAGE_SZ				XLLP_BIT_24
#define XLLP_DFC_CTRL_DWIDTH_M			XLLP_BIT_26
#define XLLP_DFC_CTRL_DWIDTH_C			XLLP_BIT_27
#define XLLP_DFC_CTRL_ND_RUN				XLLP_BIT_28
#define XLLP_DFC_CTRL_DMA_EN				XLLP_BIT_29
#define XLLP_DFC_CTRL_ECC_EN				XLLP_BIT_30
#define XLLP_DFC_CTRL_SPARE_EN			XLLP_BIT_31

// DFC Command Buffer 0 Register
#define XLLP_DFC_NDCB_AUTO_RS           0x02000000
#define XLLP_DFC_NDCB_CSEL_0            0x00000000
#define XLLP_DFC_NDCB_CSEL_1            0x01000000

// DFC command type
typedef enum {
	XLLP_DFC_CMD_READ		 	        = 0x00000000,
	XLLP_DFC_CMD_PROGRAM	 	        = 0x00200000,	 	
	XLLP_DFC_CMD_ERASE		 	        = 0x00400000,
	XLLP_DFC_CMD_READ_ID	 	        = 0x00600000,
	XLLP_DFC_CMD_STATUS_READ 	        = 0x00800000,
	XLLP_DFC_CMD_RESET		 	        = 0x00a00000
} XLLP_DFC_CMD_TYPE_T;						      

#define XLLP_DFC_NDCB_NC                0x00100000
#define XLLP_DFC_NDCB_DBC_SINGLE        0x00000000
#define XLLP_DFC_NDCB_DBC_DOUBLE        0x00080000
#define XLLP_DFC_NDCB_ADDR_CYC_SHIFT    16

// register bit offset 

// DFC timing 0 register
#define XLLP_DFC_TIMING_tRP     0
#define XLLP_DFC_TIMING_tRH     3
#define XLLP_DFC_TIMING_tWP     8
#define XLLP_DFC_TIMING_tWH  	11
#define XLLP_DFC_TIMING_tCS  	16
#define XLLP_DFC_TIMING_tCH  	19

// DFC timing 1 register
#define XLLP_DFC_TIMING_tAR     0
#define XLLP_DFC_TIMING_tWHR    4
#define XLLP_DFC_TIMING_tR   		16

// DFC NDSR reserved bits offset
#define XLLP_DFC_NDSR_RESERVED 0xFFF
#define XLLP_DFC_NDSR_CLEAR		0xFFF

// max value for each timing setting in DFC
#define XLLP_TIMING_MAX_tCH      7
#define XLLP_TIMING_MAX_tCS      7
#define XLLP_TIMING_MAX_tWH      7
#define XLLP_TIMING_MAX_tWP      7
#define XLLP_TIMING_MAX_tRH      7
#define XLLP_TIMING_MAX_tRP      7
#define XLLP_TIMING_MAX_tR    	 65535
#define XLLP_TIMING_MAX_tWHR     15
#define XLLP_TIMING_MAX_tAR      15

// DFC clock. constantly 104M
#define XLLP_DFC_CLOCK	104

// The following data is a rough evaluation
#define NAND_OTHER_TIMEOUT 		10 // microsecond, for readID/readStatus/reset
#define NAND_CMD_TIMEOUT		10  // microsecond, for readID/readStatus/reset

// Flash Block Lock Status
#define BLOCK_STATUS_UNLOCK 	0x06
#define BLOCK_STATUS_LOCK		0x02
#define BLOCK_STATUS_LOCK_TIGHT	0x01

// DFC data size enumeration transfered from/to controller, including padding
// (zero)to be a multiple of 32.
typedef enum {
	XLLP_DFC_DATA_SIZE_STATUS = 8,			// for ReadStatus/ReadBlockLockStatus
	XLLP_DFC_DATA_SIZE_ID = 7,			// for ReadID
	// PGSize = 512, SpareSize=16
	XLLP_DFC_DATA_SIZE_32 = 32,			// for read2
	XLLP_DFC_DATA_SIZE_512 = 512,		// for read/program disabling spare area
	XLLP_DFC_DATA_SIZE_520 = 520,   // for spare=1, ECC=1
	XLLP_DFC_DATA_SIZE_528 = 528,   // for spare=1, ECC=0
	XLLP_DFC_DATA_SIZE_544 = 544,		// NOT used for PIO, for read/program enabling spare area
	// PGSize = 2048, SpareSize = 64
	XLLP_DFC_DATA_SIZE_64 = 64,			// for read2
	XLLP_DFC_DATA_SIZE_2048 = 2048, 	// for read/program disabling spare area
	XLLP_DFC_DATA_SIZE_2096	= 2096,		// for read/program enabling spare area
	XLLP_DFC_DATA_SIZE_UNUSED = 0xFFFF
} XLLP_DFC_DATA_SIZE_T, *P_XLLP_DFC_DATA_SIZE_T;

// DFC padding size enumeration transfered from/to controller
typedef enum {
	// for ReadStatus/ReadBlockLockStatus/ReadID/
	// for Read/Program disabling spare area(Both 512 and 2048)
	// for Read/Program enabling spare area, disabling ECC
	XLLP_DFC_PADDING_SIZE_0 = 0,	
	// for read/program with SPARE_EN=1, ECC_EN=0, pgSize=512
	XLLP_DFC_PADDING_SIZE_16 = 16,
	// for read/program with SPARE_EN=1, ECC_EN=1, pgSize=512 and 2048
	XLLP_DFC_PADDING_SIZE_24 = 24,
	XLLP_DFC_PADDING_SIZE_UNUSED = 0xFFFF
} XLLP_DFC_PADDING_SIZE_T, *P_XLLP_DFC_PADDING_SIZE_T;



// The low level primitives
XLLP_STATUS_T XllpFlashDfcSetGPIO(P_XLLP_DFC_CONTEXT_T pContext);

//void XllpFlashDfcSetClock(P_XLLP_DFC_CONTEXT_T pContext, XLLP_BOOL_T bEnable);

void XllpFlashDfcSetTiming(P_XLLP_DFC_CONTEXT_T pContext);

void XllpFlashDfcSetDMA(P_XLLP_DFC_CONTEXT_T pContext);

void XllpFlashDfcSetECC(P_XLLP_DFC_CONTEXT_T pContext);

void XllpFlashDfcSetSpare(P_XLLP_DFC_CONTEXT_T pContext);

XLLP_STATUS_T XllpFlashDfcGetPattern(P_XLLP_DFC_CONTEXT_T pContext, 
		XLLP_UINT16_T cmd, P_XLLP_DFC_DATA_SIZE_T pDataSize, 
		P_XLLP_DFC_PADDING_SIZE_T pPaddingSize);

XLLP_STATUS_T XllpFlashDfcSendCommand(P_XLLP_DFC_CONTEXT_T pContext, 
		XLLP_UINT16_T cmd, XLLP_UINT32_T addr, XLLP_UINT8_T numPages);
		
void XllpFlashDfcRun(P_XLLP_DFC_CONTEXT_T pContext);
			
void XllpFlashDfcStop(P_XLLP_DFC_CONTEXT_T pContext);

//void XllpFlashDfcClearECC(P_XLLP_DFC_CONTEXT_T pContext);

//void XllpFlashDfcClearPGCNT(P_XLLP_DFC_CONTEXT_T pContext);			
			
void XllpFlashDfcReadFIFOPartial(P_XLLP_DFC_CONTEXT_T pContext, 
		P_XLLP_UINT8_T pBuffer, XLLP_UINT32_T bytes,
		XLLP_DFC_DATA_SIZE_T dataSize);
			
void XllpFlashDfcWriteFIFOPartial(P_XLLP_DFC_CONTEXT_T pContext, 
		P_XLLP_UINT8_T pBuffer, XLLP_UINT32_T bytes,
		XLLP_DFC_DATA_SIZE_T dataSize);

void XllpFlashDfcReadFIFO(P_XLLP_DFC_CONTEXT_T pContext, 
		P_XLLP_UINT8_T pBuffer, XLLP_UINT32_T bytes);
			
void XllpFlashDfcWriteFIFO(P_XLLP_DFC_CONTEXT_T pContext, 
		P_XLLP_UINT8_T pBuffer, XLLP_UINT32_T bytes);

void XllpFlashDfcReadDFCStatus(P_XLLP_DFC_CONTEXT_T pContext, 
		P_XLLP_UINT32_T pStatus);
			
void XllpFlashDfcReadPageCounter(P_XLLP_DFC_CONTEXT_T pContext, 
		P_XLLP_UINT32_T pPageCounter);
			
void XllpFlashDfcReadBadBlockAddr(P_XLLP_DFC_CONTEXT_T pContext, 
		P_XLLP_UINT32_T pBadBlockAddr);
			
void XllpFlashDfcEnableInt(P_XLLP_DFC_CONTEXT_T pContext, 
		XLLP_UINT32_T intMask);
			
void XllpFlashDfcDisableInt(P_XLLP_DFC_CONTEXT_T pContext, 
		XLLP_UINT32_T intMask);
			
void XllpFlashDfcClearInt(P_XLLP_DFC_CONTEXT_T pContext, 
		XLLP_UINT32_T intMask);
			
// high level primitives
XLLP_STATUS_T XllpFlashDfcInit(P_XLLP_DFC_CONTEXT_T pContext);

XLLP_STATUS_T XllpFlashDfcInitNOGPIO(P_XLLP_DFC_CONTEXT_T pContext);

XLLP_STATUS_T XllpFlashDfcWrite (P_XLLP_DFC_CONTEXT_T pContext, 
		P_XLLP_UINT8_T pBuffer, XLLP_UINT32_T startPage, 
		XLLP_UINT32_T numPages, XLLP_UINT32_T timeout, 
		P_XLLP_UINT32_T pBadBlockNum);
			
XLLP_STATUS_T XllpFlashDfcRead (P_XLLP_DFC_CONTEXT_T pContext, 
		P_XLLP_UINT8_T pBuffer, XLLP_UINT32_T bufBytesPerPG, 
		XLLP_UINT32_T startPage, XLLP_UINT32_T numPages, 
		XLLP_UINT32_T timeout, P_XLLP_UINT32_T eccErrorPageNum);
			
XLLP_STATUS_T XllpFlashDfcErase (P_XLLP_DFC_CONTEXT_T pContext, 
		XLLP_UINT32_T startBlock, XLLP_UINT32_T numBlocks, 
		XLLP_UINT32_T timeout, P_XLLP_UINT32_T pBadBlockNum);
			
XLLP_STATUS_T XllpFlashDfcReadID (P_XLLP_DFC_CONTEXT_T pContext, 
		P_XLLP_UINT8_T pMakerID, P_XLLP_UINT8_T pDevID);
			
XLLP_STATUS_T XllpFlashDfcReadStatus (P_XLLP_DFC_CONTEXT_T pContext, 
		P_XLLP_UINT8_T pStatus);

XLLP_STATUS_T XllpFlashDfcReset (P_XLLP_DFC_CONTEXT_T pContext);

XLLP_STATUS_T 
XllpFlashDfcReadLockStatus (P_XLLP_DFC_CONTEXT_T pContext, XLLP_UINT32_T block,
							P_XLLP_UINT8_T pStatus);

XLLP_STATUS_T XllpFlashDfcLock (P_XLLP_DFC_CONTEXT_T pContext);

XLLP_STATUS_T XllpFlashDfcUnlock (P_XLLP_DFC_CONTEXT_T pContext, 
			XLLP_UINT32_T startBlock, XLLP_UINT32_T blockNum);

			
#endif //__XLLP_DFC_H			
